#pragma once

/*
用户使用muduo库编写服务器程序
*/

#include "noncopyable.h"
#include "EventLoop.h"
#include "Acceptor.h"
#include "InetAddress.h"
#include "EventLoopThreadPool.h"
#include "Callbacks.h"
#include "TcpConnetion.h"
#include "Timestamp.h"
#include "Buffer.h"

#include <functional>
#include <string>
#include <atomic>
#include <unordered_map>



// 对外的服务器编程所用的类
class TcpServer : noncopyable
{
public:
    using ThreadInitCallback = std::function<void(EventLoop*)>;

    enum Option
    {
        kNoReusePort,
        kReusePort,
    };

    TcpServer(EventLoop* loop, const InetAddress &listenAddr, 
                        const std::string nameArg,
                        Option option = kNoReusePort);
    ~TcpServer();

    // 设置底层subloop的个数
    void setThreadNum(int numThreads);
    void setThreadInitCallback(const ThreadInitCallback& cb) { threadInitCallback_ = cb; }
    void setConnectionCallback(const ConnectionCallback &cb) { connectionCallback_ = cb; }
    void setMessageCallback(const MessageCallback &cb) { messageCallback_ = cb; }
    void setWriteCompleteCallback(const WriteCompleteCallback &cb) { writeCompleteCallback_ = cb; }

    // 开启服务器监听
    void start();



private:
    void newConnection(int sockfd, const InetAddress &peerAddr);
    void removeConnection(const TcpConnectionPtr &conn);
    void removeConncetionInLoop(const TcpConnectionPtr &conn);


    using ConnectionMap = std::unordered_map<std::string, TcpConnectionPtr>;

    EventLoop* loop_; // 用户定义的loop baseloop

    const std::string ipPort_;
    const std::string name_;

    std::unique_ptr<Acceptor> acceptor_; // 运行在mainloop,监听新连接事件

    std::shared_ptr<EventLoopThreadPool> threadPool_; // one loop per thread

    ConnectionCallback connectionCallback_; // 有新连接时回调
    MessageCallback messageCallback_; // 有读写消息时回调
    WriteCompleteCallback writeCompleteCallback_; // 消息发送完成后回调

    ThreadInitCallback threadInitCallback_; // loop线程初始化回调
    std::atomic_int started_;

    int nextConnId_;
    ConnectionMap connections_;

};